package com.wcs.exam.controller.biz;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.wcs.exam.common.base.BaseBiz;
import com.wcs.exam.dao.CategoryDao;
import com.wcs.exam.dao.impl.mapper.entity.Category;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.*;

import static java.util.stream.Collectors.toList;

@Slf4j
@Component
@RequiredArgsConstructor
public class CategoryCommonBiz extends BaseBiz {

    @NotNull
    private final CategoryDao dao;

    /**
     * 根据指定的ID递归获取其所有子节点的ID列表。
     *
     * @param id 指定的分类ID，用于查找对应的分类及其子分类。
     * @return 包含所有子节点ID的列表。如果指定ID对应的分类不存在，则返回空列表。
     */
    public List<Long> listChildrenIdById(Long id) {
        // 根据ID从数据库中获取对应的分类对象
        Category category = dao.getById(id);
        if (ObjectUtil.isNull(category)) {
            // 如果分类对象为空，返回一个空的ID列表
            return Collections.emptyList();
        }

        // 获取与当前分类类型相同的分类列表
        List<Category> categoryList = dao.listByCategoryType(category.getCategoryType());

        // 递归获取指定ID的所有子节点ID
        return recursionChildrenIds(id, categoryList);
    }



    /**
     * 根据类别类型和一组类别ID，列出所有子类别的ID
     * 此方法用于递归地收集给定类别ID的所有子类别ID，基于类别类型筛选
     *
     * @param categoryType 类别类型，用于筛选类别
     * @param ids 类别ID集合，表示需要查询的父类别
     * @return 包含所有子类别ID的列表
     */
    public List<Long> listChildrenIdByIds(Integer categoryType, Collection<Long> ids) {
        // 根据类别类型从数据库中获取所有相关类别
        List<Category> categoryList = dao.listByCategoryType(categoryType);
        // 如果类别列表为空，则直接返回空列表
        if (CollectionUtil.isEmpty(categoryList)) {
            return Collections.emptyList();
        }

        // 使用HashSet存储结果ID，以避免重复
        Set<Long> resultIds = new HashSet<>();
        // 遍历每个类别ID，递归查找其子类别ID
        for (Long id : ids) {
            // 递归获取子类别ID列表
            List<Long> childrenIds = recursionChildrenIds(id, categoryList);
            // 如果子类别ID列表不为空，则将其添加到结果集中
            if (CollectionUtil.isNotEmpty(childrenIds)) {
                resultIds.addAll(childrenIds);
            }
        }
        // 将结果集转换为列表并返回
        return new ArrayList<>(resultIds);
    }

    /**
     * 递归获取指定分类的所有子分类id
     *
     * @param parentId 父分类的ID，用于查找其子分类
     * @param categoryList 所有分类的列表，用于查找子分类
     * @return 包含所有子分类id的列表如果指定的父分类没有子分类，则返回空列表
     */
    private List<Long> recursionChildrenIds(Long parentId, List<Category> categoryList) {
        // 获取父级Id相同的分类id
        List<Long> categoryIdList = categoryList.stream().filter(item -> item.getParentId().equals(parentId)).map(Category::getId).collect(toList());
        if (CollectionUtil.isEmpty(categoryIdList)) {
            return Collections.emptyList();
        }
        List<Long> resultList = new ArrayList<>(categoryIdList);

        // 同理，获取相应子集分类id
        for (Long id : categoryIdList) {
            List<Long> childrenIdList = recursionChildrenIds(id, categoryList);
            if (ObjectUtil.isNotNull(childrenIdList)) {
                resultList.addAll(childrenIdList);
            }
        }
        return resultList;
    }
}
